﻿
#ifndef __MSL_LOG_H__
#define __MSL_LOG_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>
#include <stdbool.h>
#include <pthread.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <process.h>

/* MS software version number */
#define MSL_SW_VERSION		("2.0.0")

#define MSGHEAD ("")

/* output log's level */
typedef enum {
	MSL_NOMSG = 0,
	MSL_ASSERT,
	MSL_ERROR,
	MSL_WARN,
	MSL_INFO,
	MSL_DEBUG,
	MSL_VERBOSE,
	MSL_COUNT, /* output log's level total number */
} MSL_LVL;

/* all formats index */
typedef enum {
	MSL_FMT_LVL = 1 << 0, /**< level */
	MSL_FMT_TAG = 1 << 1, /**< tag */
	MSL_FMT_TIME = 1 << 2, /**< current time */
	MSL_FMT_P_INFO = 1 << 3, /**< process info */
	MSL_FMT_T_INFO = 1 << 4, /**< thread info */
	MSL_FMT_FILE = 1 << 5, /**< file directory and name */
	MSL_FMT_FUNC = 1 << 6, /**< function name */
	MSL_FMT_LINE = 1 << 7, /**< line number */
} MSFmtIndex;

typedef enum {
	MSL_TIME_ELAPSED = 0, //0000001.180
	MSL_TIME_DETAL, //19700101|08:00:22.372
	MSL_TIME_ALL, //19700101|08:00:22.372|000001.180
} MSL_TIME_FMT;

typedef struct {
	FILE *outfd;
	int loglevel;
	size_t fmt_set[MSL_COUNT];
	unsigned int starttime; //开始时间
	MSL_TIME_FMT timefmt; //true(0000001.180) false(19700101|08:00:22.372)
} msl_t;

/* macro definition for all formats */
#define MSL_FMT_ALL    (MSL_FMT_LVL|MSL_FMT_TAG|MSL_FMT_TIME|MSL_FMT_P_INFO|MSL_FMT_T_INFO| \
    MSL_FMT_FILE|MSL_FMT_FUNC|MSL_FMT_LINE)

#define MSL_FMT_NORMAL (MSL_FMT_LVL|MSL_FMT_TIME)

#define MSL_DTIME_LEN   (22) //19700101|08:00:22.372
#define MSL_LEVEL_SIZE (4)
#define MSL_TAG_SIZE   (32)
#define MSL_FILE_SIZE  (32)
#define MSL_FUNC_SIZE  (32)
#define MSL_LINE_SIZE  (8)

#define MSL_DUMP_COL_NUM		(16)		/* 16进制: 每行列数 */
#define MSL_DUMP_LINE_MAX_SIZE	(512)		/* 16进制: 每行大小 */
#define MSL_DUMP_PAGE_MAX_LINE	(20)		/* 16进制: 每页行数 */
#define MSL_DUMP_PAGE_MAX_SIZE	(2048)		/* 16进制: 每页大小 */
#define MSL_DUMP_HEAD_STR	"\nDisplacement -1--2--3--4--5--6--7--8-Hex-0--1--2--3--4--5--6  --ASCII Value--\n"

#define msldebug(log, x, ...) { \
		if(msl_output(log, MSL_DEBUG, __FILE__, __FUNCTION__, __LINE__)) {\
			fprintf((log)->outfd, "" x, ## __VA_ARGS__);\
		}\
	}
#define mslinfo(log, x, ...) { \
		if(msl_output(log, MSL_INFO, __FILE__, __FUNCTION__, __LINE__)) {\
			fprintf((log)->outfd, "" x, ## __VA_ARGS__);\
		}\
	}

#define mslwarn(log, x, ...) { \
		if(msl_output(log, MSL_WARN, __FILE__, __FUNCTION__, __LINE__)) {\
			fprintf((log)->outfd, "" x, ## __VA_ARGS__);\
		}\
	}

#define mslerr(log, x, ...) { \
		if(msl_output(log, MSL_ERROR, __FILE__, __FUNCTION__, __LINE__)) {\
			fprintf((log)->outfd, "" x, ## __VA_ARGS__);\
		}\
	}

#define mslmemdump(log, level, msg, msglen, x, ...) { \
		if(msl_output(log, level, __FILE__, __FUNCTION__, __LINE__)) {\
			fprintf((log)->outfd, "" x, ## __VA_ARGS__);\
			memdump((log)->outfd, msg, msglen); \
		}\
	}

int msl_init(msl_t *log, const char *filename);
int msl_release(msl_t *log);

int msl_set_logout(msl_t *log, const char *filename);

int msl_set_level(msl_t *log, int level);
int msl_set_fmt(msl_t *log, int level, size_t set);
int msl_set_timefmt(msl_t *log, MSL_TIME_FMT fmt);
int msl_get_datetime(char *dtime, int len);
unsigned int msl_get_time();

bool msl_output(msl_t *log, int level, const char *file, const char *func,
		const long line);

void memdump(FILE* fd, unsigned char *addr, long len);

#ifdef  __cplusplus
}
#endif  /* end of __cplusplus */

#endif /* __MSL_LOG_H__ */
